package co.fitstart.mobile.web.controller.order;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.support.Result;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.wechat.web.interceptor.WechatJsConfig;

import co.fitstart.entity.coupon.Coupon;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.order.PaymentStatus;
import co.fitstart.entity.user.User;
import co.fitstart.mobile.service.CouponService;
import co.fitstart.mobile.service.CourseRoundService;
import co.fitstart.mobile.service.OrderService;
import co.fitstart.mobile.service.UserService;
import co.fitstart.mobile.web.interceptor.MobileDetect;
import co.fitstart.mobile.web.interceptor.Router;
import co.fitstart.mobile.web.interceptor.WechatAuthority;
import co.fitstart.mobile.web.resolver.Secure;

/**
 * 
 * @author mohanlan
 *
 */
@Controller
@RequestMapping("/orders")
public class OrderController {
    
    private static Logger logger = LoggerFactory.getLogger(OrderController.class);
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private CouponService couponService;
    
    @Autowired
    private CourseRoundService courseRoundService;
    
    @Autowired
    private UserService userService;
    
    /**
     * List order by payment status
     * 
     * @param user 
     * @param status
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @Router
    @WechatAuthority
    @MobileDetect
    @WechatJsConfig
    public ModelAndView list(@Secure User user,
                             @RequestParam(value = "paymentStatus", required = false, defaultValue = "unpaid") String status) {
        
        ModelAndView modelAndView = new ModelAndView("/order/" + status +"-order-list");
        
        List<Order> orders = orderService.list(user, PaymentStatus.aliasOf(status));
        
        modelAndView.addObject("paymentStatus", PaymentStatus.aliasOf(status));
        modelAndView.addObject("orders", orders);
        
        return modelAndView;
    }
    
    /**
     * Display order view
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/{orderId}", method = RequestMethod.GET)
    @Router
    @WechatAuthority
    @MobileDetect
    @WechatJsConfig
    public ModelAndView view(@Secure User user,
                             @PathVariable("orderId") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("/order/order-view");
        
        Order order = orderService.load(Order.class, orderId);
        Long userId = user.getId();
        
        // goes to error page when not match
        if(!order.matches(userId)) {
            modelAndView.setViewName("order-error");
            return modelAndView;
        }
        
        if(order.getOrderType().isOnline() && order.getPaymentStatus().isPaid() && order.isOnlineYear()) {
            List<Coupon> unused = new ArrayList<>();
            List<String> usedCouponIds = new ArrayList<>();
            int giveAmount = 0;
            Long doneeId = null;
            
            List<Coupon> coupons = couponService.listCoupon(order);
            for(Coupon coupon : coupons) {
                if(userId.equals(coupon.getUserId())) {
                    if(coupon.getStatus().isUsed()) {
                        usedCouponIds.add(coupon.getId() + "");
                    } else {
                        unused.add(coupon);
                    }
                } else {
                    giveAmount++;
                    doneeId = coupon.getUserId();
                }
            }
            
            //未使用优惠券
            modelAndView.addObject("unused", unused);
            
            //已购买课程
            if(usedCouponIds.size() > 0) {
                modelAndView.addObject("finishedCourseRounds", courseRoundService.list(usedCouponIds, true));
                modelAndView.addObject("onGoingCourseRounds", courseRoundService.list(usedCouponIds, false));
            }
            
            //转赠优惠券数量
            modelAndView.addObject("give", giveAmount);
            
            ////受赠人姓名
            if(doneeId != null) {
                User donee = userService.load(User.class, doneeId);
                
                if(donee != null) {
                    modelAndView.addObject("donee", donee.getName() == null ? donee.getMobile() : donee.getName());
                }
            }
        }
        
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param orderId
     * @return
     */
    @RequestMapping(value = "/shipping-address", method = RequestMethod.GET)
    @Router
    @WechatAuthority
    @MobileDetect
    @WechatJsConfig
    public ModelAndView editShippingAddress(@Secure User user,
                                            @RequestParam("order") Long orderId) {
        
        ModelAndView modelAndView = new ModelAndView("/order/order-shipping-address");
        
        Order order = orderService.load(Order.class, orderId);
        Long userId = user.getId();
        
        // goes to error page when not match
        if(!order.matches(userId)) {
            modelAndView.setViewName("order-error");
            return modelAndView;
        }
        
        modelAndView.addObject("order", order);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param orderId
     * @param address
     * @return
     */
    @RequestMapping(value = "/shipping-address", method = RequestMethod.PATCH)
    @Router
    @WechatAuthority
    @MobileDetect
    @WechatJsConfig
    public @ResponseBody String onEditShippingAddress(@Secure User user,
                                                      @RequestParam("order") Long orderId,
                                                      @RequestParam("address") String address) {
        
        Result result = new Result();
        
        try {
            
            Order order = orderService.load(Order.class, orderId);
            Long userId = user.getId();
            
            // goes to error page when not match
            if(!order.matches(userId)) {
                result.fail().message("订单数据异常!");
                return JsonUtils.toJsonString(result);
            }
            
            orderService.editShippingAddress(order, address);
            result.success().message("编辑地址成功");
            
        } catch (Exception e) {
            logger.error("#onEditShippingAddress - An error occurs when editing shipping address ", e);
            result.fail().message("编辑地址失败!");
        }
        
        return JsonUtils.toJsonString(result);
    }
}
